home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / wceole.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  27.8 KB  |  1,130 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #define TRACE_STG 0
  14. #define MAX_POSSIBLE_NAMELEN    512
  15. #define MAGIC_STORAGE    0x1234
  16. #define MAGIC_STREAM    0xabcd
  17.  
  18.  
  19. class CStreamImp;
  20.  
  21. class CStorageImp : public IStorage
  22. {
  23. public:
  24.     CStorageImp(
  25.          const OLECHAR      *pwcsName,
  26.          CStorageImp        *pParent,
  27.          CStorageImp        *pSibling,
  28.          CRITICAL_SECTION   *pCS,
  29.          HRESULT *phr);
  30.  
  31.     ~CStorageImp();
  32.  
  33.     STDMETHOD(QueryInterface) (REFIID iid, LPVOID *ppvObj);
  34.     STDMETHOD_(ULONG, AddRef) ();
  35.     STDMETHOD_(ULONG, Release) ();
  36.  
  37.     HRESULT STDMETHODCALLTYPE CreateStream(
  38.          const OLECHAR *pwcsName,
  39.          DWORD grfMode,
  40.          DWORD reserved1,
  41.          DWORD reserved2,
  42.          IStream **ppstm);
  43.     HRESULT STDMETHODCALLTYPE OpenStream(
  44.          const OLECHAR *pwcsName,
  45.          void *reserved1,
  46.          DWORD grfMode,
  47.          DWORD reserved2,
  48.          IStream **ppstm);
  49.     HRESULT STDMETHODCALLTYPE CreateStorage(
  50.          const OLECHAR *pwcsName,
  51.          DWORD grfMode,
  52.          DWORD dwStgFmt,
  53.          DWORD reserved2,
  54.          IStorage **ppstg);
  55.     HRESULT STDMETHODCALLTYPE OpenStorage(
  56.          const OLECHAR *pwcsName,
  57.          IStorage *pstgPriority,
  58.          DWORD grfMode,
  59.          SNB snbExclude,
  60.          DWORD reserved,
  61.          IStorage **ppstg);
  62.     HRESULT STDMETHODCALLTYPE CopyTo(
  63.          DWORD ciidExclude,
  64.          const IID *rgiidExclude,
  65.          SNB snbExclude,
  66.          IStorage *pstgDest);
  67.     HRESULT STDMETHODCALLTYPE MoveElementTo(
  68.          const OLECHAR *pwcsName,
  69.          IStorage *pstgDest,
  70.          const OLECHAR *pwcsNewName,
  71.          DWORD grfFlags);
  72.     HRESULT STDMETHODCALLTYPE Commit(
  73.          DWORD grfCommitFlags);
  74.     HRESULT STDMETHODCALLTYPE Revert( void);
  75.     HRESULT STDMETHODCALLTYPE EnumElements(
  76.          DWORD reserved1,
  77.          void *reserved2,
  78.          DWORD reserved3,
  79.          IEnumSTATSTG **ppenum);
  80.     HRESULT STDMETHODCALLTYPE DestroyElement(
  81.          const OLECHAR *pwcsName);
  82.     HRESULT STDMETHODCALLTYPE RenameElement(
  83.          const OLECHAR *pwcsOldName,
  84.          const OLECHAR *pwcsNewName);
  85.     HRESULT STDMETHODCALLTYPE SetElementTimes(
  86.          const OLECHAR *pwcsName,
  87.          const FILETIME *pctime,
  88.          const FILETIME *patime,
  89.          const FILETIME *pmtime);
  90.     HRESULT STDMETHODCALLTYPE SetClass(
  91.          REFCLSID clsid);
  92.     HRESULT STDMETHODCALLTYPE SetStateBits(
  93.          DWORD grfStateBits,
  94.          DWORD grfMask);
  95.     HRESULT STDMETHODCALLTYPE Stat(
  96.          STATSTG *pstatstg,
  97.          DWORD grfStatFlag);
  98.     HRESULT STDMETHODCALLTYPE Load(
  99.          HANDLE hFile);
  100.     HRESULT STDMETHODCALLTYPE Save(
  101.          HANDLE hFile);
  102.  
  103.     friend class CStreamImp;
  104.     friend class CEnumSTATSTGImp;
  105.  
  106. private:
  107.     OLECHAR*        m_pszName;
  108.     CLSID           m_clsid;
  109.     CStreamImp*     m_pFirstChildStream;
  110.     CStorageImp*    m_pFirstChildStorage;
  111.     CStorageImp*    m_pNextStorage;
  112.     CStorageImp*    m_pParentStorage;
  113.     CRITICAL_SECTION* m_pCS;
  114.     ULONG           m_Refs;
  115. };
  116.  
  117.  
  118. class CStreamImp : public IStream
  119. {
  120. public:
  121.     CStreamImp(
  122.         const OLECHAR       *pszName,
  123.         CStreamImp          *pSibling,
  124.         CStorageImp         *pParent,
  125.         CRITICAL_SECTION    *pCS,
  126.         HRESULT             *phr,
  127.         PBYTE               pData = NULL,
  128.         BOOL                fDeleteOnRelease = TRUE);
  129.  
  130.     ~CStreamImp();
  131.  
  132.     STDMETHOD(QueryInterface) (REFIID iid, LPVOID *ppvObj);
  133.     STDMETHOD_(ULONG, AddRef) ();
  134.     STDMETHOD_(ULONG, Release) ();
  135.     HRESULT STDMETHODCALLTYPE Read(
  136.         void *pv,
  137.         ULONG cb,
  138.         ULONG *pcbRead);
  139.     HRESULT STDMETHODCALLTYPE Write(
  140.         const void *pv,
  141.         ULONG cb,
  142.         ULONG *pcbWritten);
  143.     HRESULT STDMETHODCALLTYPE Seek(
  144.          LARGE_INTEGER dlibMove,
  145.          DWORD dwOrigin,
  146.          ULARGE_INTEGER *plibNewPosition);
  147.     HRESULT STDMETHODCALLTYPE SetSize(
  148.          ULARGE_INTEGER libNewSize);
  149.     HRESULT STDMETHODCALLTYPE CopyTo(
  150.          IStream *pstm,
  151.          ULARGE_INTEGER cb,
  152.          ULARGE_INTEGER *pcbRead,
  153.          ULARGE_INTEGER *pcbWritten);
  154.     HRESULT STDMETHODCALLTYPE Commit(
  155.          DWORD grfCommitFlags);
  156.     HRESULT STDMETHODCALLTYPE Revert( void);
  157.     HRESULT STDMETHODCALLTYPE LockRegion(
  158.          ULARGE_INTEGER libOffset,
  159.          ULARGE_INTEGER cb,
  160.          DWORD dwLockType);
  161.     HRESULT STDMETHODCALLTYPE UnlockRegion(
  162.          ULARGE_INTEGER libOffset,
  163.          ULARGE_INTEGER cb,
  164.          DWORD dwLockType);
  165.     HRESULT STDMETHODCALLTYPE Stat(
  166.          STATSTG *pstatstg,
  167.          DWORD grfStatFlag);
  168.     HRESULT STDMETHODCALLTYPE Clone(
  169.          IStream **ppstm);
  170.     HRESULT STDMETHODCALLTYPE Load(
  171.          HANDLE hFile);
  172.     HRESULT STDMETHODCALLTYPE Save(
  173.          HANDLE hFile);
  174.  
  175.     friend class CStorageImp;
  176.     friend class CEnumSTATSTGImp;
  177.  
  178. private:
  179.     PBYTE       m_pData;
  180.     CStreamImp* m_pNext;
  181.     OLECHAR*    m_pszName;
  182.     DWORD       m_dwSize;
  183.     DWORD       m_dwCurrentPosition;
  184.     ULONG       m_Refs;
  185.     BOOL        m_fDeleteOnRelease;
  186.     CStorageImp*        m_pParent;
  187.     CRITICAL_SECTION*   m_pCS;
  188. };
  189.  
  190.  
  191. LPVOID wce_CoTaskMemRealloc( LPVOID pv, ULONG cbOld, ULONG cb )
  192. {
  193.     ASSERT( cb > 0);
  194.  
  195.     LPVOID lpnew = CoTaskMemAlloc(cb);
  196.     if((pv != NULL) && (lpnew != NULL))
  197.     {
  198.         memcpy(lpnew, pv, cbOld);
  199.         ::CoTaskMemFree(pv);
  200.     }
  201.  
  202.     return lpnew;
  203. }
  204.  
  205. // DIALOGEX templates are not supported under WinCE, so we want to rewrite in
  206. // the DIALOG header and move over the data after DLGTEMPLATEEX structure  
  207. // and before the first dialog item.
  208. // Note: we are referring to the DLGTEMPLATEEX that's defined in the MFC headers,
  209. // NOT the definition in the online help (which isn't really a structure, just a 
  210. // format description.)
  211. // This function is only used once in occmgr.cpp.
  212. BYTE* wce_convertDialogTemplate(DLGTEMPLATE* pNewTemplate, 
  213.                                 DLGTEMPLATEEX* pOldTemplate, 
  214.                                 ULONG nOldLen) 
  215. {
  216.     ASSERT((sizeof(DLGTEMPLATE)%2) == 0);   // check to see if structure is WORD-aligned
  217.     ASSERT((sizeof(DLGTEMPLATEEX)%2) == 0); // check to see if structure is WORD-aligned
  218.  
  219.     BYTE* pNew = (BYTE*)pNewTemplate;
  220.     BYTE* pOld = (BYTE*)pOldTemplate;
  221.     int nLen;
  222.  
  223.     pNewTemplate->style = pOldTemplate->style;// & WS_EX_WCEMASK;
  224.     pNewTemplate->dwExtendedStyle = 0;
  225.     pNewTemplate->cdit = 0;
  226.     pNewTemplate->x    = pOldTemplate->x;
  227.     pNewTemplate->y    = pOldTemplate->x;
  228.     pNewTemplate->cx   = pOldTemplate->cx;
  229.     pNewTemplate->cy   = pOldTemplate->cy;
  230.  
  231.     nLen = nOldLen - sizeof(DLGTEMPLATEEX); // get everything after DLGTEMPLATEEX
  232.     memcpy(pNew + sizeof(DLGTEMPLATE), 
  233.            pOld + sizeof(DLGTEMPLATEEX), 
  234.            nLen);                          // and shift it over in a memcpy
  235.     pNew += sizeof(DLGTEMPLATE);
  236.  
  237.     if(!(pNewTemplate->style & DS_SETFONT))
  238.         pNew += nLen; // No DS_SETFONT, so we're done. Point pNew at the end. 
  239.     else
  240.     {
  241.         // There are two additional members (weight and italics) before the font name 
  242.         // that needs removal. Find it by looking for the end of the title. (In this
  243.         // case, we memcpy'd too much, but the excess will be written over here.)
  244.         WORD *pw = (WORD*)pNew; 
  245.         if (*pw == (WORD)-1)        // Skip menu name ordinal or string
  246.             pw += 2; // WORDs
  247.         else
  248.             while (*pw++);
  249.  
  250.         if (*pw == (WORD)-1)        // Skip class name ordinal or string
  251.             pw += 2; // WORDs
  252.         else
  253.             while (*pw++);
  254.  
  255.         while (*pw++);              // Skip caption string
  256.  
  257.         pw++;                       // Skip pointsize
  258.         pw++;                       // Skip weight (will be deleted)
  259.         pw++;                       // Skip italics (will be deleted)
  260.  
  261.         // We're at the font name, so shift it over.
  262.         do
  263.         {
  264.             *(pw-2) = *pw;
  265.         } 
  266.         while(*pw++);
  267.         pw -= 2; // move to the new end of the font name
  268.  
  269.         // We're now at the end, so we're done!  Get the new pNew.
  270.         pNew = (BYTE*)pw;
  271.     }
  272.  
  273.     return pNew;
  274. }
  275.  
  276. // Shrink the DLGITEMTEMPLATEEX down to a DLGITEMTEMPLATE, done in the 
  277. // similar fashion as we did for the header (rewrite structure,
  278. // and copy over the post-structure information)
  279. // This function is only used once in occmgr.cpp.
  280. BYTE* wce_convertDialogItemTemplate(DLGITEMTEMPLATE* pNewItemTemplate, 
  281.                                     DLGITEMTEMPLATEEX* pOldItemTemplate, 
  282.                                     ULONG nOldLen)
  283. {
  284.     const int DLGITEMTEMPLATEEX_ERROR = 2; 
  285.     BYTE* pNew = (BYTE*)pNewItemTemplate;
  286.     BYTE* pOld = (BYTE*)pOldItemTemplate;
  287.     int nLen;
  288.  
  289.     pNewItemTemplate->style = pOldItemTemplate->style;
  290.     pNewItemTemplate->dwExtendedStyle = 0;
  291.     pNewItemTemplate->x  = pOldItemTemplate->x;
  292.     pNewItemTemplate->y  = pOldItemTemplate->y;
  293.     pNewItemTemplate->cx = pOldItemTemplate->cx;
  294.     pNewItemTemplate->cy = pOldItemTemplate->cy;
  295.     pNewItemTemplate->id = LOWORD(pOldItemTemplate->id);
  296.  
  297.     nLen = nOldLen - sizeof(DLGITEMTEMPLATEEX);
  298.     memcpy(pNew + sizeof(DLGITEMTEMPLATE), 
  299.            pOld + sizeof(DLGITEMTEMPLATEEX), 
  300.            nLen);
  301.     pNew += sizeof(DLGITEMTEMPLATE) + nLen + DLGITEMTEMPLATEEX_ERROR;
  302.  
  303.     return pNew;
  304. }
  305.  
  306.  
  307. HRESULT wce_CLSIDFromProgID(LPCOLESTR lpszProgID, LPCLSID pclsid)
  308. {
  309. #if (_WIN32_WCE >= 210)
  310.     return CLSIDFromProgID(lpszProgID,pclsid);
  311. #else // _WIN32_WCE
  312.     WCHAR sz[256];
  313.     ULONG cbValue = sizeof(sz);
  314.     HKEY hSubKey;
  315.     LONG lResult;
  316.  
  317.     if (lpszProgID == NULL)
  318.         return(E_INVALIDARG);
  319.  
  320.     if (*lpszProgID == 0)
  321.         return(CO_E_CLASSSTRING);
  322.  
  323.     _tcscpy(sz, lpszProgID);
  324.     _tcscat(sz, _T("\\Clsid"));
  325.  
  326.     lResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, sz, 0, 0, &hSubKey);
  327.     if (lResult == ERROR_SUCCESS)
  328.     {
  329.         TCHAR strValueName[60];
  330.         DWORD dwValueNameLength;
  331.         DWORD dwType;
  332.         lResult = RegEnumValue(hSubKey, 0, strValueName, &dwValueNameLength, 0, &dwType, (LPBYTE)sz, &cbValue);
  333.         ASSERT(dwType == REG_SZ);
  334.         ASSERT(lResult == ERROR_SUCCESS);
  335.         return CLSIDFromString(sz, pclsid);
  336.     }
  337.     return E_FAIL;
  338. #endif // _WIN32_WCE
  339. }
  340.  
  341.  
  342. void wce_ReleaseStgMedium( LPSTGMEDIUM pMedium )
  343. {
  344. #if (_WIN32_WCE >= 210)
  345.     ReleaseStgMedium(pMedium);
  346. #else // _WIN32_WCE
  347.     if(pMedium == NULL)
  348.         return;
  349.  
  350.     BOOL fPunkRel = pMedium->pUnkForRelease != NULL;
  351.  
  352.     switch (pMedium->tymed) {
  353.         case TYMED_HGLOBAL:
  354.             if (pMedium->hGlobal != NULL && !fPunkRel)
  355.                 VERIFY(WCE_FCTN(GlobalFree)(pMedium->hGlobal) == 0);
  356.             break;
  357.  
  358. /* WinCE: these are not supported by the OS
  359.         case TYMED_GDI:
  360.             if (pMedium->hGlobal != NULL && !fPunkRel)
  361.                 DeleteObject(pMedium->hGlobal);
  362.             break;
  363.  
  364.         case TYMED_ENHMF:
  365.             if (pMedium->hEnhMetaFile != NULL && !fPunkRel)
  366.             {
  367.                     VERIFY(DeleteEnhMetaFile(pMedium->hEnhMetaFile));
  368.             };
  369.             break;
  370.         case TYMED_MFPICT:
  371.             if (pMedium->hGlobal != NULL && !fPunkRel) {
  372.                 LPMETAFILEPICT  pmfp;
  373.  
  374.                 if ((pmfp = (LPMETAFILEPICT)GlobalLock(pMedium->hGlobal)) == NULL)
  375.                     break;
  376.  
  377.                 DeleteMetaFile(pmfp->hMF);
  378.                 GlobalUnlock(pMedium->hGlobal);
  379.                 VERIFY(WCE_FCTN(GlobalFree)(pMedium->hGlobal) == 0);
  380.             }
  381.             break;
  382. */
  383.         case TYMED_FILE:
  384.             if (pMedium->lpszFileName != NULL) {
  385. //                if (!IsValidPtrIn(pMedium->lpszFileName, 1))
  386.   //                  break;
  387.                 if (!fPunkRel) {
  388.                     DeleteFile(pMedium->lpszFileName);
  389.                 }
  390.  
  391.     //  WARNING: there was a bug in the 16bit code that the filename
  392.     //  string was not being freed if pUnkForRelease was NULL. the
  393.     //  spec says it should delete the string, so we follow the spec
  394.     //  here.
  395.                 free(pMedium->lpszFileName);
  396.                 pMedium->lpszFileName = NULL;
  397.  
  398.             }
  399.             break;
  400.  
  401.         case TYMED_ISTREAM:
  402.             if (pMedium->pstm != NULL)// &&
  403. //                IsValidInterface(pMedium->pstm))
  404.                 pMedium->pstm->Release();
  405.             break;
  406.  
  407.         case TYMED_ISTORAGE:
  408.             if (pMedium->pstg != NULL)// &&
  409. //                IsValidInterface(pMedium->pstg))
  410.                 pMedium->pstg->Release();
  411.             break;
  412.  
  413.         case TYMED_NULL:
  414.             break;
  415.  
  416.         default:
  417.             ASSERT(FALSE);
  418. //            AssertSz(FALSE, "Invalid medium in ReleaseStgMedium");
  419.     }
  420.  
  421.  
  422.     if (pMedium->pUnkForRelease) {
  423.         //if (IsValidInterface(pMedium->pUnkForRelease))
  424.             pMedium->pUnkForRelease->Release();
  425.         pMedium->pUnkForRelease = NULL;
  426.     }
  427.  
  428.     // NULL out to prevent unwanted use of just freed data.
  429.     // Note: this must be done AFTER punkForRelease is called
  430.     // because our special punkForRelease used in remoting
  431.     // needs the tymed value.
  432.  
  433.     pMedium->tymed = TYMED_NULL;
  434. #endif // _WIN32_WCE
  435. }
  436.  
  437.  
  438. SCODE wce_OleInitialize( LPVOID pvReserved )
  439. {
  440.     return(::CoInitializeEx(NULL,COINIT_MULTITHREADED));
  441. }
  442.  
  443. void wce_OleUninitialize()
  444. {
  445.     ::CoUninitialize();
  446. }
  447.  
  448. HRESULT wce_CoDisconnectObject( IUnknown*, unsigned long )
  449. {
  450.         return S_OK;
  451. }
  452.  
  453.  
  454.  
  455. ////////////////////////////////////////////////////////////////////////////
  456. //
  457. HRESULT wce_CreateStreamOnHGlobal(
  458.     HGLOBAL     hGlobal,
  459.     BOOL        fDeleteOnRelease,
  460.     LPSTREAM *  ppstm)
  461. {
  462.     HRESULT             hr;
  463.  
  464.     DWORD dwSize = WCE_FCTN(GlobalSize)(hGlobal);
  465.  
  466.     *ppstm = new CStreamImp(
  467.                     NULL, // WinCE: sneak in size as workaround (see ctor)
  468.                     (CStreamImp*)dwSize,
  469.                     NULL,
  470.                     NULL,  // pointer to Critical Section
  471.                     &hr,
  472.                     (PBYTE)hGlobal,
  473.                     fDeleteOnRelease);
  474.  
  475.     if ((*ppstm == NULL) ||
  476.         (hr != S_OK))
  477.     {
  478.         if (*ppstm == NULL)
  479.         {
  480.             return E_OUTOFMEMORY;
  481.         }
  482.         else
  483.         {
  484.             delete ppstm;
  485.         }
  486.     }
  487.  
  488.     return hr;
  489. }
  490.  
  491.  
  492. //////////////////////////////////////////////////////////////////////////////
  493. //
  494. HRESULT wce_OleLoadFromStream ( LPSTREAM pStm, REFIID iidInterface,
  495.     LPVOID FAR* ppvObj)
  496. {
  497.     //  Assumptions:  The name of the object class is in the stream,
  498.     //  as a length-prefixed string.
  499.     HRESULT         hresult = NOERROR;
  500.     CLSID               cid;
  501.     LPPERSISTSTREAM pPS;
  502.     LPUNKNOWN       pUnk;
  503.  
  504.     *ppvObj = NULL;
  505.  
  506.     if ((hresult = ::ReadClassStm(pStm, &cid)) != NOERROR)
  507.         goto errRtn;
  508.  
  509.     hresult = ::CoCreateInstance(cid, NULL,
  510.         CLSCTX_SERVER,
  511.         iidInterface,
  512.         (LPVOID FAR *) &pUnk);
  513.     if (hresult)
  514.         goto errRtn;
  515.     hresult = pUnk->QueryInterface(IID_IPersistStream,
  516.         (LPVOID FAR*) &pPS);
  517.     if (!hresult)
  518.     {
  519.         hresult = pPS->Load( pStm );
  520.         pPS->Release();
  521.     }
  522.     if (!hresult)
  523.         hresult = pUnk->QueryInterface(iidInterface, ppvObj );
  524.     pUnk->Release();
  525.  
  526. errRtn:
  527.  
  528.     return hresult;
  529. }
  530.  
  531.  
  532. //////////////////////////////////////////////////////////////////////////////
  533. //
  534. HRESULT wce_OleSaveToStream ( LPPERSISTSTREAM pPStm, LPSTREAM pStm)
  535. {
  536.  
  537.     HRESULT hresult = 0;
  538.     CLSID   clsid;
  539.  
  540.     if (!pPStm)
  541.     {
  542.         hresult = ResultFromScode(OLE_E_BLANK);
  543.         goto errRtn;
  544.     }
  545.  
  546.     if (hresult = pPStm->GetClassID(&clsid))
  547.         goto errRtn;
  548.  
  549.     if ((hresult = ::WriteClassStm(pStm, clsid)) != NOERROR)
  550.         goto errRtn;
  551.  
  552.     hresult = pPStm->Save(pStm, TRUE);
  553.  
  554. errRtn:
  555.     return hresult;
  556. }
  557.  
  558.  
  559. HRESULT wce_OleTranslateColor(OLE_COLOR clr, HPALETTE hpal, COLORREF* lpcolorref)
  560. {
  561.     if(lpcolorref != NULL)
  562.     {
  563.         if(clr & 0x80000000L) 
  564.         {
  565.             // GetSysColor for WinCE requires the 2nd MSB to be set in 
  566.             // addition to the low byte index.
  567.             *lpcolorref = GetSysColor((clr & 0x000000FFL) | 0x40000000L);
  568.         }
  569.         else 
  570.         {
  571.             // Note: if the high byte is 0x02, then the normal OleTranslateColor
  572.             // will use the optional palette.  We are ignoring that case and
  573.             // returning the RGB value directly.
  574.             *lpcolorref = (COLORREF)(clr & 0x00FFFFFFL);
  575.         }
  576.     }
  577.     return S_OK;
  578. }
  579.  
  580.  
  581. HRESULT wce_OleCreateFontIndirect(void* lpFontDesc, REFIID riid, LPVOID* lplpvObj)
  582. {
  583.     return CCeFont::CreateFont((LPFONTDESC)lpFontDesc, riid, lplpvObj);
  584. }
  585.  
  586.  
  587.  
  588. //////////////////////////////////////////////////////////////////////////////
  589. //
  590. LRESULT CALLBACK wce_IMMWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
  591. {
  592.     // All this window proc does is gobble up any messages that get sent via TranslateAccelerator
  593.     // below.  See comment below.
  594.     return 0;
  595. }
  596.  
  597. ////////////////////////////////////////////////////////////////////////////
  598. //
  599. //  CStreamImp::CStreamImp
  600. //
  601. ////////////////////////////////////////////////////////////////////////////
  602.  
  603. ////////////////////////////////////////////////////////////////////////////
  604. //
  605.  
  606. CStreamImp::CStreamImp(
  607.     const OLECHAR       *pszName,
  608.     CStreamImp          *pSibling,
  609.     CStorageImp         *pParent,
  610.     CRITICAL_SECTION    *pCS,
  611.     HRESULT             *phr,
  612.     PBYTE               pData,
  613.     BOOL                fDeleteOnRelease)
  614. {
  615.     m_dwSize = 0;
  616.     if (pData != NULL)
  617.     {
  618. // WinCE: we pass in the size via *pSibling (otherwise NULL in this workaround context)
  619.         // m_dwSize = CoTaskMemSize(pData);    
  620.         m_dwSize = (DWORD)pSibling;
  621.         pSibling = NULL;
  622.     }
  623.     m_fDeleteOnRelease = fDeleteOnRelease;
  624.     m_dwCurrentPosition = 0;
  625.     m_pData = pData;
  626.     m_Refs = 1;
  627.     m_pParent = pParent;
  628.     m_pNext = pSibling;
  629. //    m_pCS = pCS;
  630.  
  631.     if (pszName != NULL)
  632.     {
  633.         m_pszName = new OLECHAR[lstrlen(pszName) + 1];
  634.         if (m_pszName == NULL)
  635.         {
  636.             *phr = STG_E_INSUFFICIENTMEMORY;
  637.             return;
  638.         }
  639.         lstrcpy(m_pszName, pszName);
  640.     }
  641.     else
  642.     {
  643.         m_pszName = NULL;
  644.     }
  645.  
  646.     *phr = S_OK;
  647. }
  648.  
  649. ////////////////////////////////////////////////////////////////////////////
  650. //
  651. CStreamImp::~CStreamImp()
  652. {
  653.     if (m_fDeleteOnRelease)
  654.     {
  655.         CoTaskMemFree(m_pData);
  656.     }
  657.     delete[] m_pszName;
  658.     if (m_pParent == NULL)
  659.     {
  660. //        DeleteCriticalSection(m_pCS);
  661.         delete m_pCS;
  662.     }
  663. }
  664.  
  665. ////////////////////////////////////////////////////////////////////////////
  666. //
  667. ULONG CStreamImp::AddRef()
  668. {
  669.     if (m_pParent != NULL)
  670.     {
  671.         return m_pParent->AddRef();
  672.     }
  673.  
  674.     InterlockedIncrement((LONG*)&m_Refs);
  675.     return m_Refs;
  676. }
  677.  
  678. ////////////////////////////////////////////////////////////////////////////
  679. //
  680. ULONG CStreamImp::Release()
  681. {
  682.     ULONG Refs;
  683.  
  684.     if (m_pParent != NULL)
  685.     {
  686.         return m_pParent->Release();
  687.     }
  688.  
  689.     Refs = m_Refs;
  690.     if (InterlockedDecrement((LONG*)&m_Refs) == 0)
  691.     {
  692.         delete this;
  693.         return 0;
  694.     }
  695.  
  696.     return Refs;
  697. }
  698.  
  699. ////////////////////////////////////////////////////////////////////////////
  700. //
  701. HRESULT CStreamImp::QueryInterface(REFIID riid, LPVOID *ppv)
  702. {
  703.     if (IsEqualIID(riid, IID_IUnknown) ||
  704.         IsEqualIID(riid, IID_IStream))
  705.     {
  706.         *ppv = (LPUNKNOWN) this ;
  707.         AddRef();
  708.         return S_OK;
  709.     }
  710.  
  711.     *ppv = NULL;
  712.     return E_NOINTERFACE ;
  713. }
  714.  
  715. ////////////////////////////////////////////////////////////////////////////
  716. //
  717. HRESULT CStreamImp::Read(
  718.         void *pv,
  719.         ULONG cb,
  720.         ULONG *pcbRead)
  721. {
  722.     ULONG cbRead = 0;
  723.  
  724.     DEBUGMSG(TRACE_STG, (L"CStreamImp::Read(%X,%d)\n",pv,cb));
  725.  
  726.     //
  727.     //  Make sure the current position is within the data
  728.     //
  729.  
  730. //    EnterCriticalSection(m_pCS);
  731.  
  732.     if (m_dwSize > m_dwCurrentPosition)
  733.     {
  734.         if (cb > (m_dwSize - m_dwCurrentPosition))
  735.         {
  736.             cbRead = m_dwSize - m_dwCurrentPosition;
  737.         }
  738.         else
  739.         {
  740.             cbRead = cb;
  741.         }
  742.  
  743.         memcpy(
  744.             pv,
  745.             m_pData + m_dwCurrentPosition,
  746.             cbRead);
  747.  
  748.         m_dwCurrentPosition += cbRead;
  749.     }
  750.  
  751. //    LeaveCriticalSection(m_pCS);
  752.  
  753.     if (pcbRead != NULL)
  754.     {
  755.         *pcbRead = cbRead;
  756.     }
  757.  
  758.     return S_OK;
  759. }
  760.  
  761. ////////////////////////////////////////////////////////////////////////////
  762. //
  763. HRESULT CStreamImp::Write(
  764.         const void *pv,
  765.         ULONG cb,
  766.         ULONG *pcbWritten)
  767. {
  768.     DEBUGMSG(TRACE_STG, (L"CStreamImp::Write\n"));
  769.  
  770. //    EnterCriticalSection(m_pCS);
  771.  
  772.     if ((m_dwCurrentPosition + cb) > (unsigned)m_dwSize)
  773.     {
  774.         //
  775.         //  We try and grow ourselves here
  776.         //
  777.  
  778.         PBYTE pData = (PBYTE)CoTaskMemRealloc(
  779.                     m_pData,
  780.                     (m_dwCurrentPosition + cb));
  781.  
  782.         if (pData == NULL)
  783.         {
  784. //            LeaveCriticalSection(m_pCS);
  785.             return STG_E_MEDIUMFULL;
  786.         }
  787.  
  788.         m_dwSize = m_dwCurrentPosition + cb;
  789.         m_pData = pData;
  790.     }
  791.  
  792.     //
  793.     //  Copy the data
  794.     //
  795.  
  796.     memcpy(m_pData + m_dwCurrentPosition, pv, cb);
  797.  
  798.     if (pcbWritten != NULL)
  799.     {
  800.         *pcbWritten = cb;
  801.     }
  802.  
  803.     //
  804.     //  Update our position
  805.     //
  806.  
  807.     m_dwCurrentPosition += cb;
  808.  
  809. //    LeaveCriticalSection(m_pCS);
  810.  
  811.     return S_OK;
  812. }
  813.  
  814. ////////////////////////////////////////////////////////////////////////////
  815. //
  816. HRESULT CStreamImp::Seek(
  817.      LARGE_INTEGER dlibMove,
  818.      DWORD dwOrigin,
  819.      ULARGE_INTEGER *plibNewPosition)
  820. {
  821.     LONG lMove = (LONG)dlibMove.QuadPart;
  822.  
  823.     DEBUGMSG(
  824.         TRACE_STG,
  825.         (L"CStreamImp::Seek(%ld,%X,%ld)\n",lMove,
  826.         dwOrigin,m_dwCurrentPosition));
  827.  
  828. //    EnterCriticalSection(m_pCS);
  829.  
  830.     switch (dwOrigin)
  831.     {
  832.     case STREAM_SEEK_CUR:
  833.  
  834.  
  835.         lMove += (LONG)m_dwCurrentPosition;
  836.  
  837.         // Fall through
  838.  
  839.     case STREAM_SEEK_SET:
  840.  
  841.         // Make sure we don't go past the begining
  842.  
  843.         if (lMove < 0)
  844.         {
  845. //            LeaveCriticalSection(m_pCS);
  846.             return STG_E_INVALIDPOINTER;
  847.         }
  848.  
  849.         m_dwCurrentPosition = (DWORD)lMove;
  850.         break;
  851.  
  852.     case STREAM_SEEK_END:
  853.  
  854.         // Make sure we don't go past the begining
  855.         if (lMove > (LONG)m_dwSize)
  856.         {
  857. //            LeaveCriticalSection(m_pCS);
  858.             return STG_E_INVALIDPOINTER;
  859.         }
  860.  
  861.         m_dwCurrentPosition = (DWORD)((LONG)m_dwSize - lMove);
  862.         break;
  863.  
  864.     default:
  865. //        LeaveCriticalSection(m_pCS);
  866.         return STG_E_INVALIDFUNCTION;
  867.  
  868.     }
  869.  
  870.     //
  871.     //  Return the new position if the user asked for it.
  872.     //
  873.  
  874.     if (plibNewPosition != NULL)
  875.     {
  876.         plibNewPosition->QuadPart = m_dwCurrentPosition;
  877.     }
  878.  
  879. //    LeaveCriticalSection(m_pCS);
  880.     return S_OK;
  881. }
  882.  
  883. ////////////////////////////////////////////////////////////////////////////
  884. //
  885. HRESULT CStreamImp::SetSize(
  886.      ULARGE_INTEGER libNewSize)
  887. {
  888.     PBYTE pData;
  889.  
  890.     DEBUGMSG(TRACE_STG, (L"CStreamImp::SetSize\n"));
  891.  
  892. //    EnterCriticalSection(m_pCS);
  893.  
  894.     pData = (PBYTE)CoTaskMemRealloc(
  895.                 m_pData,
  896.                 libNewSize.LowPart);
  897.  
  898.     if (pData == NULL)
  899.     {
  900. //        LeaveCriticalSection(m_pCS);
  901.         return STG_E_MEDIUMFULL;
  902.     }
  903.  
  904.     m_dwSize = libNewSize.LowPart;
  905.     m_pData = pData;
  906.  
  907. //    LeaveCriticalSection(m_pCS);
  908.  
  909.     return S_OK;
  910. }
  911.  
  912. ////////////////////////////////////////////////////////////////////////////
  913. //
  914. HRESULT CStreamImp::CopyTo(
  915.      IStream *pstm,
  916.      ULARGE_INTEGER cb,
  917.      ULARGE_INTEGER *pcbRead,
  918.      ULARGE_INTEGER *pcbWritten)
  919. {
  920.     return E_NOTIMPL;
  921. }
  922.  
  923. ////////////////////////////////////////////////////////////////////////////
  924. //
  925. HRESULT CStreamImp::Commit(
  926.      DWORD grfCommitFlags)
  927. {
  928.     return E_NOTIMPL;
  929. }
  930.  
  931. ////////////////////////////////////////////////////////////////////////////
  932. //
  933. HRESULT CStreamImp::Revert( void)
  934. {
  935.     return E_NOTIMPL;
  936. }
  937.  
  938. ////////////////////////////////////////////////////////////////////////////
  939. //
  940. HRESULT CStreamImp::LockRegion(
  941.      ULARGE_INTEGER libOffset,
  942.      ULARGE_INTEGER cb,
  943.      DWORD dwLockType)
  944. {
  945.     return E_NOTIMPL;
  946. }
  947.  
  948. ////////////////////////////////////////////////////////////////////////////
  949. //
  950. HRESULT CStreamImp::UnlockRegion(
  951.      ULARGE_INTEGER libOffset,
  952.      ULARGE_INTEGER cb,
  953.      DWORD dwLockType)
  954. {
  955.     return E_NOTIMPL;
  956. }
  957.  
  958. ////////////////////////////////////////////////////////////////////////////
  959. //
  960. HRESULT CStreamImp::Stat(
  961.      STATSTG *pstatstg,
  962.      DWORD grfStatFlag)
  963. {
  964.     return E_NOTIMPL;
  965. }
  966.  
  967. ////////////////////////////////////////////////////////////////////////////
  968. //
  969. HRESULT CStreamImp::Clone(
  970.      IStream **ppstm)
  971. {
  972.     if (ppstm != NULL)
  973.     {
  974.         *ppstm = (IStream*)m_pData;
  975.     }
  976.     return E_NOTIMPL;
  977. }
  978.  
  979. ////////////////////////////////////////////////////////////////////////////
  980. //
  981. HRESULT CStreamImp::Load(HANDLE hFile)
  982. {
  983.     DWORD    dwMagic,dwSize,dwRW;
  984.  
  985.     DEBUGMSG(TRACE_STG, (L"CStreamImp::Load(%s)\n", m_pszName));
  986.  
  987.     //    must be a brand new CStream to call serialize
  988.     if (m_pszName != NULL || m_pData != NULL)
  989.     {
  990.         return STG_E_ACCESSDENIED;
  991.     }
  992.  
  993.     //    make sure the magic number
  994.     if (!ReadFile(hFile, &dwMagic, sizeof(DWORD), &dwRW, NULL))
  995.     {
  996.         return    STG_E_FILEALREADYEXISTS;
  997.     }
  998.  
  999.     if (dwMagic != MAGIC_STREAM)
  1000.     {
  1001.         return    STG_E_FILEALREADYEXISTS;
  1002.     }
  1003.  
  1004.     //    read the name size and name
  1005.     if (!ReadFile(hFile, &dwSize, sizeof(DWORD), &dwRW, NULL))
  1006.     {
  1007.         return STG_E_FILEALREADYEXISTS;
  1008.     }
  1009.  
  1010.     if (dwSize<=0 || dwSize>MAX_POSSIBLE_NAMELEN)
  1011.     {
  1012.         return STG_E_FILEALREADYEXISTS;
  1013.     }
  1014.  
  1015.     m_pszName = new WCHAR[dwSize/sizeof(WCHAR)];
  1016.  
  1017.     if (m_pszName == NULL)
  1018.     {
  1019.         return STG_E_INSUFFICIENTMEMORY;
  1020.     }
  1021.     if (!ReadFile(hFile, m_pszName, dwSize, &dwRW, NULL) || dwRW != dwSize)
  1022.     {
  1023.         return STG_E_FILEALREADYEXISTS;
  1024.     }
  1025.  
  1026.     //    read the data size and data
  1027.     if (!ReadFile(hFile, &m_dwSize, sizeof(DWORD), &dwRW, NULL) || m_dwSize < 0)
  1028.     {
  1029.         return STG_E_FILEALREADYEXISTS;
  1030.     }
  1031.  
  1032.     if (m_dwSize != 0)
  1033.     {
  1034.         m_pData = (PBYTE)CoTaskMemAlloc(m_dwSize);
  1035.  
  1036.         if (m_pData == NULL)
  1037.         {
  1038.             return STG_E_INSUFFICIENTMEMORY;
  1039.         }
  1040.  
  1041.         if (!ReadFile(hFile, m_pData, m_dwSize, &dwRW, NULL) ||
  1042.             (dwRW != m_dwSize))
  1043.         {
  1044.             DEBUGMSG(TRACE_STG,(L"ReadFile Failed %ld %ld %X\n",dwRW, dwSize,GetLastError()));
  1045.             return STG_E_FILEALREADYEXISTS;
  1046.         }
  1047.     }
  1048.  
  1049.     return S_OK;
  1050. }
  1051.  
  1052. ////////////////////////////////////////////////////////////////////////////
  1053. //
  1054. HRESULT CStreamImp::Save(HANDLE hFile)
  1055. {
  1056.     DWORD    dwMagic,dwSize,dwRW;
  1057.  
  1058.     if (m_pszName == NULL)
  1059.     {
  1060.         return STG_E_ACCESSDENIED;
  1061.     }
  1062.  
  1063.     //    first write the storage magic number
  1064.     dwMagic = MAGIC_STREAM;
  1065.     if (!WriteFile(hFile, &dwMagic, sizeof(DWORD), &dwRW, NULL))
  1066.     {
  1067.         return STG_E_MEDIUMFULL;
  1068.     }
  1069.  
  1070.     //    write the size of the name first
  1071.     dwSize = (lstrlen(m_pszName)+1)*sizeof(WCHAR);
  1072.     if(!WriteFile(hFile, &dwSize, sizeof(DWORD), &dwRW, NULL))
  1073.     {
  1074.         return STG_E_MEDIUMFULL;
  1075.     }
  1076.  
  1077.     //    write the name
  1078.     if (!WriteFile(hFile, m_pszName, dwSize, &dwRW, NULL))
  1079.     {
  1080.         return STG_E_MEDIUMFULL;
  1081.     }
  1082.  
  1083.  
  1084.     //    write the data size and data
  1085.     if (!WriteFile(hFile, &m_dwSize, sizeof(DWORD), &dwRW, NULL))
  1086.     {
  1087.         return STG_E_MEDIUMFULL;
  1088.     }
  1089.  
  1090.     if (m_dwSize && !m_pData)
  1091.     {
  1092.         return STG_E_MEDIUMFULL;
  1093.     }
  1094.  
  1095.     if (m_pData)
  1096.     {
  1097.         if(!WriteFile(hFile, m_pData, m_dwSize, &dwRW, NULL))
  1098.         {
  1099.             return STG_E_MEDIUMFULL;
  1100.         }
  1101.     }
  1102.  
  1103.     DEBUGMSG(TRACE_STG, (L"CStreamImp::Save(%s)\n",m_pszName));
  1104.  
  1105.     return    S_OK;
  1106. }
  1107.  
  1108.  
  1109.  
  1110. AFX_MODULE_STATE* AFXAPI _AfxGetOleModuleState();
  1111.  
  1112. void wce_UnregisterOleWindowClasses()
  1113. {
  1114.     AFX_MANAGE_STATE(_AfxGetOleModuleState());
  1115.     // unregister Window classes
  1116.     AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  1117.     AfxLockGlobals(CRIT_REGCLASSLIST);
  1118.     LPTSTR lpsz = pModuleState->m_szUnregisterList;
  1119.     while (*lpsz != 0)
  1120.     {
  1121.         LPTSTR lpszEnd = _tcschr(lpsz, '\n');
  1122.         ASSERT(lpszEnd != NULL);
  1123.         *lpszEnd = 0;
  1124.         UnregisterClass(lpsz, AfxGetInstanceHandle());
  1125.         lpsz = lpszEnd + 1;
  1126.     }
  1127.     pModuleState->m_szUnregisterList[0] = 0;
  1128.     AfxUnlockGlobals(CRIT_REGCLASSLIST);
  1129. }
  1130.